/**
 * ...
 * @author Thot
 */
															/* POO Simulation*/
															/* Utils*/





//------------------------------------------------
//----------------------Observer--------------------
//------------------------------------------------
//------------------------------------------------

function Observer()
{
	this._listeners = new Array();
}


Observer.prototype._listeners = null;


Observer.prototype.destroy = function()
{
	this._listeners = null;
};

Observer.prototype.addListener = function( p_eventType, p_callback, p_context )
{
	this._listeners.push( {type:p_eventType, callback:p_callback, context:p_context} );
};

Observer.prototype.removeListener = function( p_eventType, p_callback, p_context )
{
	var listeners = new Array();
	var max = this._listeners.length;
	var listener = null;
	var i = 0;
	
	for( i = 0; i < max; i++ )
	{
		listener = this._listeners[i];
		if( listener.type == p_eventType && listener.callback == p_callback && listener.context == p_context )
		{
			continue;
		}
		listeners.push( listener );
	}
	
	this._listeners = listeners;
};

Observer.prototype.dispatchEvent = function( p_eventType, p_params )
{
	
	var params = p_params || null;
	var max = this._listeners.length;
	var listener = null;
	var calls = new Array();
	var i = 0;
	
	
	for( i = 0; i < max; i++ )
	{
		listener = this._listeners[i];
		if( listener.type == p_eventType )
		{
			calls.push(listener);
		}
	}
	
	max = calls.length;
	
	for( i = 0; i < max; i++ )
	{
		listener = calls[i];
		listener.callback.apply( listener.context, [p_eventType,params] );
	}
	
};




													/* Utils*/
													
													
													
													
													
													/*MVC patterns implementations*/
 
 
	
	

	
//------------------------------------------------
//--------------------FACADE----------------------
//------------------------------------------------
//------------------------------------------------
 
	
function Facade()
{
}


	// static
	
	Facade._instance = null;

	Facade.getInstance = function()
	{
		Facade._instance = Facade._instance || new Facade();
		return Facade._instance;
	};
	
	
	
	// private
	
	Facade.prototype._controller = null;
	Facade.prototype._model = null;
	Facade.prototype._view = null;
	
	// public
	
	Facade.prototype.init = function()
	{
		this._controller 	= Controller.getInstance();
		this._model 		= Model.getInstance();
		this._view 			= View.getInstance();
		
		this._controller.facade = this;
		this._model.facade 		= this;
		this._view.facade 		= this;
	};
	
	Facade.prototype.registerCommand = function( p_notificationType, p_commandClass )
	{
		this._controller.registerCommand( p_notificationType, p_commandClass );
	};
	
	Facade.prototype.removeCommand = function( p_notificationType )
	{
		this._controller.removeCommand( p_notificationType );
	};
	

	
	Facade.prototype.registerProxy = function( p_name, p_proxy )
	{
		this._model.registerProxy( p_name, p_proxy );
	};
	
	Facade.prototype.removeProxy = function( p_name )
	{
		this._model.removeProxy( p_name );
	};

	Facade.prototype.getProxy = function( p_name )
	{
		return this._model.getProxy( p_name );
	};

	
	
	Facade.prototype.registerMediator = function( p_name, p_proxy )
	{
		this._view.registerMediator( p_name, p_proxy );
	};
	
	Facade.prototype.removeMediator = function( p_name )
	{
		this._view.removeMediator( p_name );
	};

	Facade.prototype.getMediator = function( p_name )
	{
		return this._view.getMediator( p_name );
	};

	
	
	
	Facade.prototype.sendNotification = function( p_notificationType, p_notification )
	{
		this._controller.notify( p_notificationType, p_notification );
		this._model.notify( p_notificationType, p_notification );
		this._view.notify( p_notificationType, p_notification );
	};
	

	

	
	
	
	
	
	
	
	
	
	

//------------------------------------------------
//--------------------CONTROLLER--------------------
//------------------------------------------------
//------------------------------------------------

function Controller()
{
	this._map 	= new Object();
	this.facade = null;
}
	// static

	Controller._instance 	= null;

	Controller.getInstance = function()
	{
		Controller._instance = Controller._instance || new Controller();
		return Controller._instance;
	};
	
	// private
	
	Controller.prototype._map 			= null;
	
	
	// public
	
	Controller.prototype.facade 		= null;
	
	Controller.prototype.registerCommand = function( p_flag, p_class )
	{
		this._map[p_flag] = p_class;
	};
	
	Controller.prototype.removeCommand = function( p_flag )
	{
		delete this._map[p_flag];
	};
	
	Controller.prototype.notify = function( p_event, p_data )
	{
		
		if( this._map[p_event] ==  null || this._map[p_event] == undefined )
		{
			return;
		}
		
		var instance = new this._map[p_event]();
		instance.execute( p_event, p_data );
	};

	
	
	
	
	
	
	
	
	
	
	
	
	

//------------------------------------------------
//--------------------MODEL--------------------
//------------------------------------------------
//------------------------------------------------

function Model()
{
	this._map 	= new Object();
	this.observer = new Observer();
	this.facade = null;
}
	

	// static

	Model._instance 	= null;

	Model.getInstance = function()
	{
		Model._instance = Model._instance || new Model();
		return Model._instance;
	};
	
	
	// private
	
	Model.prototype._map 		= null;
	
	
	// public
	
	Model.prototype.observer 		= null;
	Model.prototype.facade 		= null;
	
	Model.prototype.registerProxy = function( p_flag, p_data )
	{
		this._map[p_flag] = p_data;
	};
	
	Model.prototype.removeProxy = function( p_flag )
	{
		delete this._map[p_flag];
	};
	
	Model.prototype.getProxy = function( p_flag )
	{
		return this._map[p_flag];
	};
	
	Model.prototype.notify = function( p_event, p_data )
	{
		this.observer.dispatchEvent( p_event, p_data );
	};
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	

//------------------------------------------------
//--------------------VIEW--------------------
//------------------------------------------------
//------------------------------------------------

function View()
{
	this._map 	= new Object();
	this.observer = new Observer();
	this.facade = null;
}
	

	// static

	View._instance 	= null;

	View.getInstance = function()
	{
		View._instance = View._instance || new View();
		return View._instance;
	};
	
	
	// private
	
	View.prototype._map 		= null;
	
	
	// public
	
	View.prototype.observer 	= null;
	View.prototype.facade 		= null;
	
	View.prototype.registerMediator = function( p_flag, p_data )
	{
		this._map[p_flag] = p_data;
	};
	
	View.prototype.removeMediator = function( p_flag )
	{
		delete this._map[p_flag];
	};
	
	View.prototype.getMediator = function( p_flag )
	{
		return this._map[p_flag];
	};
	
	View.prototype.notify = function( p_event, p_data )
	{
		this.observer.dispatchEvent( p_event, p_data );
	};
	
	
	
	
	
	
	
	
	

	
	
	
	
												/*PATTERNS*/
	
	///////////////////////////////
	///////////////////////////////
	/////////////COMMAND///////////
	///////////////////////////////
	//////////////////////////////
	
	
function Command()
{
}

	Command.prototype.execute = function( p_notificationType, p_data ){};
	
	
		
	///////////////////////////////
	///////////////////////////////
	/////////////MACROCOMMAND///////////
	///////////////////////////////
	//////////////////////////////
	
function MacroCommand()
{
}

	//private
	
	MacroCommand.prototype._commands = null;
	
	
	//public

	MacroCommand.prototype.addSubCommand = function( p_command )
	{
		
		this._commands = this._commands || new Array();
		this._commands.push( p_command );
	};
	
	MacroCommand.prototype.removeSubCommand = function( p_command )
	{
		this._commands = this._commands || new Array();
		var index = this._commands.indexOf( p_command );
		
		if( index > -1 )
		{
			this._commands.splice( index, 1 );
		}
	};
	
	
	MacroCommand.prototype.execute = function( p_notificationType, p_data )
	{
		var i = 0;
		var max = 0;
		var command = null;
		this._commands = this._commands || new Array();
		
		max = this._commands.length;
		
		for( i = 0; i < max; i++ )
		{
			command = new this._commands[i]();
			command.execute( p_notificationType, p_data );
		}
		
	};
	
	
	
	
	
	///////////////////////////////
	///////////////////////////////
	/////////////PROXY///////////
	///////////////////////////////
	//////////////////////////////
	
	
	
function Proxy()
{
	
}
	

	// private
	
	Proxy.prototype._data = null;
	Proxy.prototype.name = "";

	// public
	
	Proxy.prototype.init = function( p_name, p_data )
	{
		this.name = p_name;
		this._data = p_data;
	};
	
	Proxy.prototype.addNotificationListener = function( p_notificationType )
	{
		Model.getInstance().observer.addListener( p_notificationType, this.onNotification, this );
	};
	
	Proxy.prototype.removeNotificationListener = function( p_notificationType )
	{
		Model.getInstance().observer.removeListener( p_notificationType, this.onNotification, this );
	};
	
	Proxy.prototype.onNotification = function( p_notificationType, p_data )
	{
		
	};
	
	Proxy.prototype.getData = function()
	{
		return this._data;
	};
	
	Proxy.prototype.getFacade = function()
	{
		return Model.getInstance().facade;
	};
	
	
	
	
	
	
	
	///////////////////////////////
	///////////////////////////////
	/////////////MEDIATOR///////////
	///////////////////////////////
	//////////////////////////////
	
	
	
function Mediator()
{
}
	

	// private
	
	Mediator.prototype._data 	= null;
	Mediator.prototype.name 	= null;

	// public
	
	Mediator.prototype.init = function( p_name, p_data )
	{
		this._data = p_data;
		this.name = p_name;
	};
	
	Mediator.prototype.addNotificationListener = function( p_notificationType )
	{
		View.getInstance().observer.addListener( p_notificationType, this.onNotification, this );
	};
	
	Mediator.prototype.removeNotificationListener = function( p_notificationType )
	{
		View.getInstance().observer.removeListener( p_notificationType, this.onNotification, this );
	};
	
	Mediator.prototype.onNotification = function( p_notificationType, p_data )
	{
		
	};
	
	Mediator.prototype.getViewComponent = function()
	{
		return this._data;
	};
	
	Mediator.prototype.getFacade = function()
	{
		return View.getInstance().facade;
	};
	
	
	
	
	

	
	

	


